<template>
  <div class="sendMsgBox" :style="isShowWaitTime ? '' : 'border-radius: 10px'">
    <el-popover
      ref="emoji"
      :offset="18"
      placement="top-start"
      width="400"
      trigger="click"
      popper-class="emojiPopover v7-micro"
      v-model="faceVisible"
    >
      <div>
        <span
          v-for="emoji in emojiConfig.bookArray"
          :key="emoji.index"
          class="emojiCardItem"
          :style="`
            width: ${emojiConfig.emojiSize}px;
            height: ${emojiConfig.emojiSize}px;
            background: url(${doMain + emojiConfig.elvesFigureUrl}) no-repeat;
            background-size: 1000% auto;
            background-position: ${-(
              emojiConfig.emojiSize *
              (emoji.index % emojiConfig.columnNum)
            )}px ${-(
            emojiConfig.emojiSize *
            parseInt(emoji.index / emojiConfig.columnNum)
          )}px;
          `"
          v-show="!emoji.isPassive"
          @click="handleClickEmojiItem(emoji)"
        ></span>
      </div>
    </el-popover>
    <!-- 最后一条消息是访客发送并且等待时间大于零展示访客等待时长 -->
    <div class="waitTime" v-if="isShowWaitTime">
      <webchatWaitTime
        :color="'#fff'"
        :visitorStartWaitTimestamp="currentSession.visitorStartWaitTimestamp"
      ></webchatWaitTime>
    </div>
    <messageCount :isCenter='showAgent ? true: false'></messageCount>
    <div class="agentBox" v-show="showAgent">
      <ul>
        <li
          class="cursor_li"
          v-for="(item, index) in agentList"
          :key="index"
        >
          <el-tooltip
            v-if="item.contentText"
            effect="dark"
            :content="item.contentText"
            slot="reference"
            placement="top"
          >
            <span class="ellipsis">{{ item.contentText }}</span>
          </el-tooltip>
          <p v-if="item.contentText" class="agentIconBox">
            <el-tooltip effect="dark" content="发送" placement="top">
              <i
                @click.stop="adopt(item, 1)"
                class="V7_iconfont V7_iconV7tubiao_fasong"
              />
            </el-tooltip>
            <el-tooltip effect="dark" content="使用" placement="top">
              <i
                @click.stop="adopt(item, 2)"
                class="V7_iconfont V7_iconV7tubiao_jilu"
              />
            </el-tooltip>
            <remarkModal
              v-if="agentData && isIndexChannel"
              :onOK="(remark) => sendRemarkMsg({ remark, ...item })"
            >
              <el-tooltip effect="dark" content="纠错" placement="top">
                <i class="V7_iconfont V7_iconV7tubiao_jiucuo" />
              </el-tooltip>
            </remarkModal>
          </p>
        </li>
      </ul>
    </div>
    <div class="sendMsgContent">
      <div class="toolbar">
        <span
          class="V7_iconfont V7_iconV7tubiao_zaixian-biaoqing"
          slot="reference"
          v-popover:emoji
        ></span>
        <el-upload
          ref="uploadItem"
          class="upLoad"
          :show-file-list="false"
          accept=".jpg, .gif, .png, .bmp"
          action=""
          multiple
          :limit="9"
          :on-exceed="handleExceed"
          :on-success="uploadImgSuccess"
          :on-error="upImgloadError"
          :onProgress="onImgProgress"
          :before-upload="beforeImgUpload"
          :http-request="uploadImgRequest"
        >
          <span class="V7_iconfont V7_iconV7tubiao_zaixian-tupian"></span>
        </el-upload>
        <el-upload
          class="upLoad"
          :show-file-list="false"
          v-show="webchatInfo.platform !== 'ocpc'"
          accept=".txt, .xlsx, .xls, .docx, .doc, .pdf, .ppt, .pptx, .key, .mp3, .wave, .mpeg, .midi, .mp4"
          action=""
          :on-success="uploadFileSuccess"
          :on-error="upFileloadError"
          :onProgress="onFileProgress"
          :before-upload="beforeFileUpload"
          :http-request="uploadFileRequest"
        >
          <span class="V7_iconfont V7_iconV7tubiao_zaixian-wenjian"></span>
        </el-upload>
        <el-tooltip effect="dark" content="点击发送满意度评价" placement="top">
          <span
            class="V7_iconV7tubiao_manyidu-20 V7_iconfont"
            @click="sendCsrFun"
            v-if="isShowCrs"
          ></span>
        </el-tooltip>
      </div>
      <div class="suggest" v-show="showSuggest === true">
        <ul>
          <li
            class="cursor_li ellipsis"
            v-for="(item, index) in quickReplyArr"
            :key="index"
            @click.stop="suggestListAdd(item.content)"
            :class="item.flag ? 'active' : ''"
          >
            <span v-if="item.content">{{ item.content }}</span>
          </li>
        </ul>
      </div>
      <textarea
        id="webchatSendMsg"
        maxlength="1000"
        @keydown="selectItemDown"
        v-model="sendMsg.sendContent"
        @keyup="selectItem($event)"
        placeholder="按enter键发送消息，按ctrl+enter换行"
      ></textarea>
      <div class="sendMsgBar">
        <el-button
          type="primary"
          class="replyMsg fr"
          @click.stop="replyMsg(null)"
          size="mini"
          >发送</el-button
        >
        <span class="fr">{{ sendMsg.sendContent.length }}/1000</span>
      </div>
    </div>
    <paste-img v-if="!$parent.isEmpty" :webchatInfo="webchatInfo"></paste-img>
    <drop-file v-if="!$parent.isEmpty" :webchatInfo="webchatInfo"></drop-file>
    <el-dialog title="提示" :visible.sync="dialogVisible" width="30%">
      <span
        >您发送的内容包含敏感词'{{
          sensitiveWords.join(';')
        }}',请确认是否继续发送</span
      >
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogCancel(sendMsg.sendContent)">取 消</el-button>
        <el-button type="primary" @click="dialogConfirm">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-property-decorator'
import { deepClone, getCurrentDateTime, filterXSS, isHasFuncOrMenus, commonAction } from '@/utils/common'
import { WebchatModule } from '@/store/modules/webchat'
import { uploadQiniu } from '@/utils/upload'
import { filterContent } from '@/utils/richFilter'
import webchatWaitTime from '@/views/webchat/common/webchatWaitTime.vue'
import { SendMsgObj, ScrollObj, EmojiObj, SuggestListProps, Usage } from '@/views/webchat/webchatInterface'
import PasteImg from './common/pasteImg.vue'
import DropFile from './common/dropFile.vue'
import remarkModal from './common/remarkModal.vue'
import debounce from 'lodash/debounce';
import messageCount from '@/views/webchat/messageCount.vue'
import { FilterXSS } from 'xss'
@Component({
  name: 'webchatSendMsg',
  components: { webchatWaitTime, PasteImg, DropFile, remarkModal, messageCount }
})
export default class WebchatSendMsg extends Vue {
  @Prop() private webchatInfo
  @Prop() private webchatDisabled
  private $store: any
  private $message: any
  private $route: any
  private $bus: any
  private $getCache: any

  private dialogVisible = false

  private sensitiveWords: any = []

  private timeout: any = null

  private selectIndex: number = -1 // 本次选中的index

  private doMain: string = '' // 上传域名

  private faceVisible: boolean = false // 是否展示表情

  private imgName: any // 图片名

  private userHeadImg = require('../../assets/img/userAgent.png')

  private showSuggest = false // 是否显示输入建议弹窗

  private count = 0

  private file: any = { // 文件名
    name: '', // 文件名
    size: '', // 文件大小
    timeStamp: '' // 上传创建的时间戳
  }

  private sendMsg = { // 发送
    sendContent: '' // 发送内容
  }

  private emojiConfig: any = {} // 表情配置

  private messageObj: any = {} // 发送消息obj

  private quickReplyArr: any = [] // 快捷回复

  @Watch('webchatInfo')
  // 点击card消息框获得焦点
  private webchatInfoChange () {
    if (!this.webchatDisabled) {
      const dom: any = document.getElementById('webchatSendMsg')
      if (dom) {
        dom.focus()
      }
    }
  }

  get currentSession () { // 当前会话的信息是实时更新，会话详情的信息是不会更新的。所以要取会话上的信息
    return WebchatModule.webchatList.webchat_todo && WebchatModule.webchatList.webchat_todo.find(item => {
      return item._id === this.$route.path.split('/')[4]
    })
  }

  get isShowWaitTime () { // 是否展示访客等待时长
    return this.currentSession && this.currentSession.lastMessage &&
      ['withrawMsg', 'customer'].includes(this.currentSession.lastMessage.lastMessageFrom) && this.currentSession.visitorStartWaitTimestamp > 0
  }

  get isShowCrs () { // 是否展示满意度发送按钮
    const channelList = this.$store.state.common.publicCache.channelList // 渠道信息列表
    const satisfactionListObj = this.$store.state.common.publicCache.satisfactionListObj // 满意度模板
    const { accessId } = this.webchatInfo
    const currentChannel = channelList.find((item: any) => { // 获取当前会话的渠道信息
      return item.accessId === accessId
    })
    if (currentChannel && currentChannel.isSatisfaction) { // 渠道开启满意度，去满意度模板查看满意度模板中是否开启了座席发送满意度，反之不显示
      if (currentChannel.satisfactionId) {
        const currentCrs = satisfactionListObj[currentChannel.satisfactionId]
        return !!(currentCrs && currentCrs.isAgentPushCsr)
      } else {
        return true
      }
    } else {
      return false
    }
  }

  get webchatType () {
    return this.$route.path.split('/')[3] || ''
  }

  get agentData () {
    return this.$store.state.webchat.agentData
  }

  get showAgent () {
    return this.agentList.length > 0 && this.isIndexChannel
  }

  get agentList () {
    return this.agentData?.list || []
  }

  get isIndexChannel () {
    return this.agentData?._id === this.currentSession?._id
  }

  private setAgent (data: {} | null) {
    WebchatModule.SET_AGENT_DATA(data)
  }

  private adopt (data: any, usage: Usage) {
    commonAction({
      url: '/im-robot/action/xbot/humanAssistAccept',
      method: 'POST',
      data: {
        robotId: this.webchatInfo.robotAssistId,
        questionId: data.questionId,
        question: data.question,
        usage
      }
    }).then(() => {
      const isSend = usage === Usage.SEND
      if (isSend) {
        this.replyMsg({
          content: data.content
        })
      } else {
        this.sendMsg.sendContent = filterContent(data.content)
      }
      this.setAgent(null)
    }).catch(err => console.log(err))
  }

  private selectItem (event: any) {
    if (event.ctrlKey && event.keyCode === 13) {
      return
    }
    document.getElementsByClassName('suggest')[0].scrollTop = 0
    const keyWord = this.sendMsg.sendContent.trim()
    if (keyWord === '') {
      this.showSuggest = false
      this.selectIndex = -1
      return false
    } else {
      const liLength = this.quickReplyArr.length // 获取列表数量
      if (event.keyCode === 38 || event.keyCode === 40) {
        if (liLength > 0) {
          // 上移
          if (event.keyCode === 38) {
            this.selectIndex -= 1
            if (this.selectIndex <= -1) {
              this.selectIndex = this.quickReplyArr.length - 1
            }
            if (this.selectIndex !== -1) {
              this.sendMsg.sendContent = this.quickReplyArr[this.selectIndex].content
              this.moveAutoCompItem(this.sendMsg.sendContent)
            }
            document.getElementsByClassName('suggest')[0].scrollTop = 26 * (this.selectIndex - 3)
            this.quickReplyArr.forEach((item) => {
              item.flag = false
            })
            if (this.selectIndex >= 0) {
              this.quickReplyArr[this.selectIndex].flag = true
            }
          }
          // 下移
          if (event.keyCode === 40) {
            this.selectIndex += 1
            if (this.selectIndex > this.quickReplyArr.length - 1) {
              this.selectIndex = 0
            }
            if (this.selectIndex !== -1) {
              this.sendMsg.sendContent = this.quickReplyArr[this.selectIndex].content
              this.moveAutoCompItem(this.sendMsg.sendContent)
            }
            document.getElementsByClassName('suggest')[0].scrollTop = 26 * (this.selectIndex - 3)
            this.quickReplyArr.forEach((item) => {
              item.flag = false
            })
            if (this.selectIndex >= 0) {
              this.quickReplyArr[this.selectIndex].flag = true
            }
          }
        }
      } else if (event.keyCode === 13) {
        this.showSuggest = false
        this.suggestListAdd(keyWord)
      } else if (isHasFuncOrMenus('input_association', this.$store.state.common.session.user, true)) { // 有智能联想权限
        this.quickReplayAutoComplete(keyWord)
      }
      // 预知输入
      const globalConfig = this.$store.state.common.publicCache.globalConfig[0]
      if (globalConfig && globalConfig.isAgentTypeNotice) {
        const platform = this.currentSession.platform;
        // 以下渠道才可以使用预知输入
        const allowPlatformList = ['wap', 'wxmini', 'weixin', 'pc', 'sdk']
        if (allowPlatformList.indexOf(platform) > -1) {
          this.typeNotice(keyWord)
        }
      }
    }
  }

  private typeNotice = debounce((content) => {
    const sessionId = this.currentSession._id
    const visitorId = this.currentSession.visitorId
    const platform = this.currentSession.platform
    const accessId = this.currentSession.accessId
    commonAction({
      url: '/im-center/action/webchat/typeNotice',
      method: 'POST',
      data: {
        content,
        sessionId,
        visitorId,
        platform,
        accessId
      }
    }).then(() => {
      console.log('预知输入上传成功')
    }).catch(err => console.log(err))
  }, 500);

  // 纠错弹窗发送消息
  private sendRemarkMsg (obj: any) {
    commonAction({
      url: '/im-robot/action/xbot/agentCorrect',
      method: 'POST',
      data: {
        robotId: this.webchatInfo.robotAssistId,
        query: obj.query,
        question: obj.question,
        questionId: obj.questionId,
        correct: obj.remark
      }
    }).then(() => {
      this.$message.success('纠错成功');
    }).catch(err => console.log(err))
  }

  // 发送消息智能联想
  private quickReplayAutoComplete (data: any) {
    const showLimit = 30 // 最多显示30条
    const listNeedShow: any = [] // 需要显示的数据
    const wordClone = deepClone(this.sendMsg.sendContent)
    const word = wordClone.replace(/\r\n/g, '').replace(/\n/g, '').replace(/(^\s*)|(\s*$)/g, '').replace(/\\/g, '\\\\').replace(/\[/g, '\\[').replace(/\]/g, '\\]').replace(/\(/g, '\\(').replace(/\)/g, '\\)').replace(/\{/g, '\\{')
    if (word) {
      let list = [] // 用来进行匹配的数据
      list = this.$store.state.webchat.quickReplyList
      if (list) {
        list.forEach((item: any) => {
          let isQuick = false
          const quickContent = item.title
          const content = item.content
          if (quickContent && quickContent !== '' && word === quickContent) {
            if (listNeedShow.length < showLimit && listNeedShow.indexOf(quickContent) < 0) {
              listNeedShow.push({ ...item, content, flag: false })
              isQuick = true
            }
          }
          if (!isQuick) {
            if (content && content !== '' && content.indexOf(word) > -1) {
              if (listNeedShow.length < showLimit && listNeedShow.indexOf(content) < 0) {
                listNeedShow.push({ ...item, content, flag: false })
              }
            }
          }
        })
      }
      this.quickReplyArr = listNeedShow
      if (this.quickReplyArr.length) {
        this.moveAutoCompItem(word)
      } else {
        this.showSuggest = false
        this.selectIndex = -1
      }
    } else {
      this.showSuggest = false
      this.selectIndex = -1
    }
  }

  private moveAutoCompItem (keyWord: any) {
    let moveLeft = 40
    const fontSize = 12
    const reg = /^[\u4e00-\u9fa5]+$/
    const flag = keyWord.split('')
    if (flag.length < 40) {
      for (let j = 0; j < flag.length; j++) {
        if (!reg.test(flag[j])) {
          moveLeft += fontSize / 2
        } else {
          moveLeft += fontSize
        }
      }
    } else {
      moveLeft = 200
    }
    const dom: any = document.getElementsByClassName('suggest')[0]
    dom.style.bottom = '30px'
    dom.style.left = moveLeft + 'px'
    this.showSuggest = true
  }

  private suggestListAdd (data: any) {
    this.sendMsg.sendContent = data
    const dom: any = document.getElementById('webchatSendMsg')
    dom.focus()
    this.showSuggest = false
    this.selectIndex = -1
  }

  private dropFileSuccess (data: any) {
    this.file.name = data.fileName
    this.file.size = data.size
    this.file.timeStamp = new Date().getTime()
    const { _id, visitorId, accessId, platform, visitorName } = (this.$parent as any).webchatInfo
    const contentType = 'file'
    const sendData: any = {
      content: '',
      type: 'out',
      visitorId,
      visitorName,
      userName: '我',
      accessId,
      platform,
      timeStamp: this.file.timeStamp,
      sendStatus: 'sending',
      sessionId: _id,
      contentType,
      fileSize: data.size,
      fileName: data.fileName,
      userHeadImg: this.userHeadImg,
      createTime: getCurrentDateTime()
    }
    WebchatModule.SET_WEBCHAT_REPLYMSG(sendData)
    this.replyMsg({ contentType: 'file', content: data.url ? `/${data.url}` : '' })
  }

  private uploadFileSuccess (data: any) { // 文件上传成功
    this.replyMsg({ contentType: 'file', content: data.key ? `/${data.key}` : '' })
  }

  private upFileloadError () { // 文件上传失败
    console.log('文件上传失败')
  }

  private onFileProgress (data: any) { // 文件上传过程中
    WebchatModule.FILE_UPLOAD_PROESS({ percent: data.percent, timeStamp: this.file.timeStamp, sessionId: this.webchatInfo._id })
  }

  private handleClickEmojiItem (emoji: EmojiObj) { // 发送表情
    const textDom: any = document.getElementById('webchatSendMsg')
    const startPos = textDom.selectionStart //  获取光标选中的开始位置
    const endPos = textDom.selectionEnd //  获取光标选中的结束位置
    this.sendMsg.sendContent = this.sendMsg.sendContent.slice(0, startPos) +
      emoji.str + this.sendMsg.sendContent.slice(endPos)
    // (emoji as any).toWeixinStr + this.sendMsg.sendContent.slice(endPos)
    this.faceVisible = false
    // textDom.focus()
  }

  // 微信客服、企业微信上传图片和文件限制
  private checkIsWxkf (type: string, file: any) {
    const name = file.name
    const size = file.size / 1024 / 1024
    const ext = name.split('.')[1].toLocaleLowerCase()
    if (type === 'image') {
      if (!['png', 'jpg'].includes(ext)) {
        this.$message({ message: '只支持上传png，jpg格式的图片', type: 'error' })
        return false
      }
      if (size > 10) {
        this.$message({ message: '图片大小不能超过10MB', type: 'error' })
        return false
      }
    } else if (type === 'file') {
      if (size > 20) {
        this.$message({ message: '文件大小不能超过20MB', type: 'error' })
        return false
      }
    }
    return true
  }

  private beforeFileUpload (file: any) { // 文件上传之前
    this.file.name = file.name.replace(/\s/g, '')
    const fileSize = file.size / 1024 / 1024
    const num = String(fileSize).length - String(fileSize).indexOf('.') + 1 // 小数点位数
    if (num > 4) { // 截取小数点后三位
      this.file.size = fileSize.toFixed(3) + 'M'
    }
    if (['wxkf', 'wxwork'].includes(this.webchatInfo.platform)) {
      if (!this.checkIsWxkf('file', file)) {
        return false
      }
    } else {
      // 微信和微信小程序上传文件最大不超过10M
      const fileSizeLimit = this.webchatInfo.platform === 'weixin' || this.webchatInfo.platform === 'wxmini' ? 10 : 50
      if (fileSize > fileSizeLimit) {
        this.$message({ message: `文件大小不能超过${fileSizeLimit}M`, type: 'error' })
        return false
      }
    }
    this.file.timeStamp = new Date().getTime() // 获取当前发送消息的时间戳
    const { _id, visitorId, accessId, platform, visitorName } = this.webchatInfo
    const contentType = 'file'
    const sendData: any = { // 发送消息Mutation数据
      content: '', // 发送消息内容
      type: 'out', // 座席发送消息
      visitorId, // 访客id
      visitorName, // 访客名称
      userName: '我',
      accessId, // 接入号id
      userId: this.$store.state.common.session.user._id || '',
      platform, // 渠道来源
      timeStamp: this.file.timeStamp, // 当前时间戳
      sendStatus: 'sending', // 发送状态
      sessionId: _id, // 会话id
      contentType, // 消息类型
      fileSize: this.file.size,
      fileName: this.file.name,
      userHeadImg: this.userHeadImg, // 座席默认头像
      createTime: getCurrentDateTime() // 当前创建消息的时间
    }
    WebchatModule.SET_WEBCHAT_REPLYMSG(sendData)
  }

  private uploadFileRequest (request: any) {
    uploadQiniu({ type: 'im', fileName: this.file.name }, request)
  }

  private uploadImgSuccess (data: any, file: any, fileList: any) { // 图片上传成功
    if (data) {
      this.count++
    }
    // 判断提示只执行一次
    if (this.count === 1) {
      this.$message({
        message: '图片传输过程中，请勿切换或关闭页面',
        type: 'success',
        duration: 5000
      })
    }
    // 复制粘贴图片时不存在fileList
    if (fileList) {
      if (this.count === fileList.length) {
        (this.$refs.uploadItem as any).clearFiles()
        this.count = 0
      }
    }
    this.replyMsg({ contentType: 'image', content: data.key ? `/${data.key}` : '' })
  }

  // 上传图片提示
  private handleExceed (files: any, fileList: any) {
    this.$message.warning('单次最多可选择9张图片');
    clearTimeout(this.timeout)
    this.timeout = setTimeout(() => {
      // 模拟点击上传图片
      const uploadItem = this.$refs.uploadItem
      const uploadInner = (uploadItem as any).$refs
      uploadInner['upload-inner'].handleClick()
    }, 100)
  }

  private onImgProgress (data: any) { // 图片发送过程中
    if (data.percent === 100) {
      this.scrollToBottom({ scrollName: 'webchatContentBox', warpName: 'chatMsgBox' })
    }
  }

  private upImgloadError () { // 图片上传失败
    console.log('上传失败')
  }

  private beforeImgUpload (file: any) { // 图片上传之前
    this.imgName = file.name.replace(/\s/g, '')
    if (['wxkf', 'wxwork'].includes(this.webchatInfo.platform)) {
      if (!this.checkIsWxkf('image', file)) {
        return false
      }
    } else {
      if (file.size / 1024 / 1024 > 10) {
        this.$message({ message: '图片大小不能超过10M', type: 'error' })
        return false
      }
    }
  }

  private uploadImgRequest (request: any) {
    uploadQiniu({ type: 'im', fileName: this.imgName }, request)
  }

  private trim (data: string) { // 去掉发送内容前后空格
    const str = data
    return str.replace(/(^\s*)|(\s*$)/g, '')
  }

  private sendCsrFun () { // 发送满意度
    const { _id, visitorId, accessId, platform } = this.webchatInfo
    const sendData = {
      visitorId,
      accessId,
      platform,
      sessionId: _id
    }
    const actionData = { url: '/im-center/action/webchat/pushImCSRInfo', method: 'POST', data: sendData }
    WebchatModule.webchatCommonAction(actionData).then(res => {
      if (res) {
        this.$message.success('发送满意度成功')
      }
    })
  }

  private selectItemDown (event: any) { // 回车发送 && 回车 + ctrl 换行
    if (event.ctrlKey && event.keyCode === 13) { // 回车 + ctrl 换行
      const textDom: any = document.getElementById('webchatSendMsg')
      const value = '\n'
      const startPos = textDom.selectionStart //  获取光标选中的开始位置
      const endPos = textDom.selectionEnd //  获取光标选中的结束位置
      const content = deepClone(this.sendMsg.sendContent)
      if (startPos === 0) { // 当前光标在输入内容前
        this.sendMsg.sendContent = '\n' + content
      } else if (startPos === content.length) { // 当前光标在输入内容后
        this.sendMsg.sendContent = content + '\n'
      } else { // 当前光标在输入内容中间
        this.sendMsg.sendContent = content.substring(0, startPos) + '\n' + content.substring(endPos, textDom.value.length) //  设置换行的位置光标选中的结束位置
      }
      textDom.selectionStart = startPos + value.length
      textDom.selectionEnd = startPos + value.length
      this.$nextTick(() => {
        const newPos = startPos + 1
        textDom.setSelectionRange(newPos, newPos)
      })
    } else if (event.keyCode === 13) { // 回车发送
      this.replyMsg()
    }
  }

  private replyMsg (obj?: SendMsgObj, flag?: boolean) { // 发送消息
    const timeStamp = new Date().getTime() // 获取当前发送消息的时间戳
    const { _id, visitorId, accessId, platform, visitorName } = this.webchatInfo
    const sendContent = (obj && obj.content) || this.trim(this.sendMsg.sendContent)
    const contentType = (obj && obj.contentType) || 'text'
    this.messageObj = obj
    if (sendContent) {
      const sendData: any = { // 发送消息Mutation数据
        content: sendContent, // 发送消息内容
        type: 'out', // 座席发送消息
        visitorId, // 访客id
        visitorName, // 访客名称
        accessId, // 接入号id
        platform, // 渠道来源
        timeStamp, // 当前时间戳
        sendStatus: 'sending', // 发送状态
        sessionId: _id, // 会话id
        contentType, // 消息类型
        userName: '我',
        userId: this.$store.state.common.session.user._id || '',
        userHeadImg: this.userHeadImg, // 座席默认头像
        createTime: getCurrentDateTime() // 当前创建消息的时间
      }
      const { content } = sendData
      this.setAgent(null)
      const wordsSetting: any = this.$store.state.common.publicCache.globalConfig[0] || {}
      if (wordsSetting && wordsSetting.agentSensitiveWordsFlag && wordsSetting.agentSensitiveWords) {
        const agentSensitiveWords = wordsSetting.agentSensitiveWords.split(',')
        if (agentSensitiveWords && agentSensitiveWords.length > 0) {
          this.sensitiveWords = []
          agentSensitiveWords.forEach(item => {
            if (content.indexOf(item) !== -1) {
              this.dialogVisible = true
              const dom: any = document.getElementById('webchatSendMsg')
              if (dom) {
                dom.blur()
              }
              this.sensitiveWords.push(item)
            }
          })
        }
      }
      if (this.sensitiveWords.length === 0) {
        this.contentReply(obj)
        if (!(obj && obj.content) && contentType === 'text') {
          this.sendMsg.sendContent = '' // 清空输入框内容
        }
      }
    } else {
      this.$message({
        message: '发送消息不能为空',
        type: 'warning'
      })
    }
  }

  private contentReply (obj?: SendMsgObj) {
    const timeStamp = new Date().getTime() // 获取当前发送消息的时间戳
    const { _id, visitorId, accessId, platform, visitorName } = this.webchatInfo
    const sendContent = (obj && obj.content) || this.trim(this.sendMsg.sendContent)
    const contentType = (obj && obj.contentType) || 'text'
    if (sendContent) {
      const sendData: any = { // 发送消息Mutation数据
        content: sendContent, // 发送消息内容
        type: 'out', // 座席发送消息
        visitorId, // 访客id
        visitorName, // 访客名称
        accessId, // 接入号id
        platform, // 渠道来源
        timeStamp, // 当前时间戳
        sendStatus: 'sending', // 发送状态
        sessionId: _id, // 会话id
        contentType, // 消息类型
        userName: '我',
        userId: this.$store.state.common.session.user._id || '',
        userHeadImg: this.userHeadImg, // 座席默认头像
        createTime: getCurrentDateTime() // 当前创建消息的时间
      }
      let { content, sessionId } = sendData
      if (contentType === 'text') {
        content = filterXSS(content)
      }
      const sendActionData: any = { content, visitorId, visitorName, accessId, sessionId, timeStamp, platform, contentType } // 发送消息action参数
      const actionData: any = { url: '/im-center/action/webchat/replyMsg', method: 'POST', data: sendActionData }
      if (contentType === 'file') { // 发送文件消息的参数
        sendData.fileName = this.file.name
        sendData.fileSize = this.file.size
        sendActionData.fileName = this.file.name
        sendActionData.fileSize = this.file.size
      }
      if (window.event) { // 发送消息的时候触发的是enter回车事件  此处需要屏蔽掉回车按钮
        window.event.preventDefault()
      }
      if (contentType !== 'file') { // 文件类型不需要push新消息 此操作在文件上传之前处理
        WebchatModule.SET_WEBCHAT_REPLYMSG(sendData)
      } else { // 文件类型的时间戳需要去上传文件时的时间戳
        actionData.data.timeStamp = this.file.timeStamp
      }
      WebchatModule.webchatReplyMsg(actionData)
      if (document.getElementsByClassName('webchatContentBox').length > 0 && document.getElementsByClassName('chatMsgBox').length > 0) { // 发送完消息滚动条到最下方
        this.scrollToBottom({ scrollName: 'webchatContentBox', warpName: 'chatMsgBox' })
      }
    } else {
      this.$message({
        message: '发送消息不能为空',
        type: 'warning'
      })
    }
  }

  // 弹窗提示敏感词确定
  private dialogConfirm () {
    this.contentReply(this.messageObj)
    this.sendMsg.sendContent = '' // 清空输入框内容
    this.dialogVisible = false
    const dom: any = document.getElementById('webchatSendMsg')
    if (dom) {
      dom.focus()
    }
  }

  // 弹窗提示敏感词取消
  private dialogCancel (val) {
    this.dialogVisible = false
    const dom: any = document.getElementById('webchatSendMsg')
    if (dom) {
      dom.focus()
    }
  }

  private scrollToBottom (data: ScrollObj) { // 滚动条到最下方
    this.$nextTick(() => {
      if (document.getElementsByClassName(data.scrollName).length) {
        document.getElementsByClassName(data.scrollName)[0].scrollTop = document.getElementsByClassName(data.warpName)[0].scrollHeight + 16
      }
    })
  }

  private listenerFun (event: any) {
    if (document.getElementsByClassName('suggest').length) {
      this.showSuggest = false
      this.selectIndex = -1
    }
  }

  @Watch('$route')
  private routeChange (to: any, from: any) {
    this.faceVisible = false
    if (from.path.split('/')[3] === 'webchat_todo' && from.path.split('/').length > 4) { // 当离开当前卡片时需要把当前输入的内容存值
      WebchatModule.SET_SENDLASTCONTENT({ _id: from.path.split('/')[4], content: this.sendMsg.sendContent })
    }
    if (to.path.split('/')[3] === 'webchat_todo') {
      const currentRoute = this.$route.path.split('/')[4]
      if (to.path.split('/').length > 4 && WebchatModule.webchatSendLastContent[currentRoute] && currentRoute !== 'empty') { // 如果当前会话有输入内容需取值
        this.sendMsg.sendContent = WebchatModule.webchatSendLastContent[currentRoute]
      } else {
        this.sendMsg.sendContent = ''
      }
    } else {
      this.sendMsg.sendContent = ''
    }
  }

  private mounted () {
    const user = this.$store.state.common.session.user
    this.userHeadImg = user ? user.userIcon : require('../../assets/img/userAgent.png') // 获取座席头像
    this.emojiConfig = WebchatModule.webchatEmoji // 获取表情配置
    const initConfig = this.$store.state.common.initConfig
    const doMain = initConfig && initConfig.qiniuDomainMap ? initConfig.qiniuDomainMap.im : '' // 获取当前上传域名
    this.doMain = doMain + '/'
    this.$getCache('/im-center/action/webchat/channelCache', ['channelList', 'satisfactionList'], true)
    WebchatModule.webchatCommonAction({ url: '/im-km/quick-reply/action/quickquery/content/cache', method: 'POST' }).then(res => {
      if (res && res.data.agent && res.data.common) {
        WebchatModule.SET_QUICKREPLY_DATA(res.data)
      }
    })
    this.$bus.$on('sendInfo', (res: any) => { //
      if (this.webchatType === 'webchat_todo') {
        this.replyMsg(res)
      }
    })
    if (document.getElementById('webchatSendMsg')) {
      document.addEventListener('click', this.listenerFun)
    }
    this.$bus.$on('toEditFun', (res: any, res1: any) => {
      const content = deepClone(this.sendMsg.sendContent.trim())
      // 去除标签
      if (res.indexOf('**') !== -1 && res1) {
        // 敏感词回归
        this.sendMsg.sendContent = content + '' + filterContent(res1)
      } else {
        this.sendMsg.sendContent = content + '' + filterContent(res)
      }
    })
    this.$bus.$on('kmUse', (res: any) => {
      if (this.webchatType === 'webchat_todo') {
        const content = deepClone(this.sendMsg.sendContent.trim())
        this.sendMsg.sendContent = content + '' + res
      }
    })
  }

  private beforeDestroy () {
    this.$bus.$off('sendInfo')
    this.$bus.$off('kmUse')
    this.$bus.$off('toEditFun')
    document.removeEventListener('click', this.listenerFun)
  }
}
</script>
<style lang="stylus" scoped>
.sendMsgBox
  position relative
  border-radius 10px 0px 10px 10px
  .waitTime
    padding 0px 8px 0px 2px
    line-height 22px
    height 22px
    border-radius 4px 4px 0px 0px
    background-color #008BEE
    position absolute
    right 0px
    top -23px
  .sendMsgContent
    height 100%
    padding 10px 10px 2px 20px
    #webchatSendMsg
      width 100%
      height calc(100% - 74px)
      border none
      resize none
    #webchatSendMsg::-webkit-input-placeholder
      color #B3B9C7
    .sendMsgBar
      line-height 34px
    .sendMsgBar > span
      color #b3b9c7
    .replyMsg
      margin-left 10px
    .toolbar
      margin-bottom 16px
    .toolbar > span
      cursor pointer
      color #B3B9C7
      margin-right 13px
    .upLoad
      display inline-block
      margin-right 13px
      cursor pointer
      color #B3B9C7
.emojiHead
  height 30px
  background #FAFAFA
  .emojiIcon
    display inline-block
    width 56px
    height 30px
    text-align center
    line-height 30px
.emojiCardItem
  margin 0px 2.5px
  display inline-block
  cursor pointer
.suggest
  width 280px
  background #ffffff
  border 1px solid #E8ECF8
  box-shadow 0px 1px 4px 0px rgba(221, 226, 229, 0.78)
  position absolute
  left 30px
  max-height 200px
  z-index 100
  overflow auto
  li
    line-height 26px
    box-sizing border-box
    margin 0 6px
    color #686E84
    font-size 12px
    border-bottom 1px solid $border-main
  li:hover
    background #d7f2fd
    color #303753
  li.active
    background #d7f2fd
    color #303753
  .cursor_li
    cursor pointer
    overflow hidden
    white-space nowrap
    text-overflow ellipsis
  .cursor_li:before
    width 4px
    height 4px
    content ''
    border-radius 50%
    background #cccccc
    margin 11px 5px
    float left
.agentBox
  width 280px
  position fixed
  bottom 173px
  max-height 200px
  z-index 100
  overflow auto
  background #FFFFFF
  border 1px solid #E8ECF8
  box-shadow 0px 1px 4px 0px rgba(221, 226, 229, 0.78)
  border-radius 10px
  li
    line-height 32px
    font-weight 400
    color #303753
    box-sizing border-box
    margin 0 13px
    color #686E84
    font-size 12px
    border-bottom 1px solid #f3f3f3
  li:last-child
    border none
  li.active
    background #d7f2fd
    color #303753
  .cursor_li
    display flex
    justify-content space-between
    cursor pointer
  .ellipsis
    overflow hidden
    white-space nowrap
    text-overflow ellipsis
  .agentIconBox
    display flex
    align-items center
    i
      color #B3B9C7
      font-size 12px
      margin-left 12px
    i:hover
      color #008BEE
</style>
<style lang="stylus">
.el-popover .el-popper .emojiPopover
  padding 0px
</style>
